﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;

namespace XCommunity
{
  public static class DuckInterfaceHelper
  {

    public static T GetInterface<T>( object obj ) where T : class
    {
      Type type = typeof( T );
      if ( !type.IsInterface )
        throw new NotSupportedException();

      Type objType = obj.GetType();

      throw new NotImplementedException();

    }


    public static TypeBuilder BuildType( TypeBuilder typeBuilder, Type interfaceType, Type objType )
    {

      foreach ( var method in interfaceType.GetMethods() )
      {
        var paramTypes = method.GetParameters().Select( parameter => parameter.ParameterType ).ToArray();

        var objMethod = objType.GetMethod( method.Name, paramTypes );
        if ( objMethod == null )
          throw new InvalidOperationException();

        if ( method.ReturnType != objMethod.ReturnType )
          throw new InvalidOperationException();


        var methodBuilder = typeBuilder.DefineMethod( method.Name, MethodAttributes.Public, method.ReturnType, paramTypes );

        BuildMethod( methodBuilder, objMethod );

      }

      throw new NotImplementedException();
    }

    private static void BuildMethod( MethodBuilder methodBuilder, MethodBase method )
    {
      throw new NotImplementedException();
    }



    private class ParameterComparer : IEqualityComparer<ParameterInfo>
    {

      #region IEqualityComparer<ParameterInfo> 成员

      public bool Equals( ParameterInfo x, ParameterInfo y )
      {
        return
          x.Position == y.Position &&
          string.Compare( x.Name, y.Name, false ) == 0 &&
          x.ParameterType == y.ParameterType &&
          x.IsOut == y.IsOut;
      }

      public int GetHashCode( ParameterInfo obj )
      {
        return obj.Name.GetHashCode() ^ obj.ParameterType.GetHashCode();
      }

      #endregion
    }



    public static bool EqualsSignature( this MethodInfo method1, MethodInfo method2 )
    {
      if ( string.Compare( method1.Name, method2.Name, false ) != 0 )
        return false;

      return method1.GetParameters().SequenceEqual( method2.GetParameters(), new ParameterComparer() );
    }


  }
}
